// maze.cpp: Source for Maze abstract class.
// Written by Victor Luna Freire - victorclf@live.com
// Copyright (c) Victor Luna Freire. All rights reserved.
// Monday, October 26, 2009 12:48:10 AM

#include "maze.h"

// Static member initializations
const char Maze::NO_WALL = '0'; 
const char Maze::WALL    = '1';  


// Get adjacent cells from a given cell.
std::vector<Vec2i> Maze::get_adjacent_cells(const Vec2i &cell) const
{
	std::vector<Vec2i> adj_cells;
	adj_cells.push_back(Vec2i(cell.x - 1, cell.y));
	adj_cells.push_back(Vec2i(cell.x + 1, cell.y));
	adj_cells.push_back(Vec2i(cell.x, cell.y - 1));
	adj_cells.push_back(Vec2i(cell.x, cell.y + 1));
	
	std::vector<Vec2i> valid_adj_cells;
	for(std::vector<Vec2i>::const_iterator itr = adj_cells.begin(); itr != adj_cells.end(); ++itr)
		if(valid_cell_coords(*itr)) valid_adj_cells.push_back(*itr);

	return valid_adj_cells;
}


// Get adjacent positions from a given position.
std::vector<Vec2i> Maze::get_adjacent_pos(const Vec2i &pos) const
{
	std::vector<Vec2i> adj_pos;
	adj_pos.push_back(Vec2i(pos.x - 1, pos.y));
	adj_pos.push_back(Vec2i(pos.x + 1, pos.y));
	adj_pos.push_back(Vec2i(pos.x, pos.y - 1));
	adj_pos.push_back(Vec2i(pos.x, pos.y + 1));
	
	std::vector<Vec2i> valid_adj_pos;
	for(std::vector<Vec2i>::const_iterator itr = adj_pos.begin(); itr != adj_pos.end(); ++itr)
		if(valid_true_coords(*itr)) valid_adj_pos.push_back(*itr);

	return valid_adj_pos;
}


// Finish the building, process all steps. Returns false if the build is over.
bool Maze::all_steps() 
{
	// Is the maze already built?
	if(is_done()) return false;
	
	// Do all steps
	while(next_step()); 
	
	// Build finished.
	return true;
}



// Output maze representation.
std::ostream& operator<<(std::ostream& ost, const Maze& m) 
{
	for(std::vector<std::string>::const_iterator vec_itr = m.maze.begin(); vec_itr != m.maze.end(); ++vec_itr) {
		for(std::string::const_iterator s_itr = vec_itr->begin(); s_itr != vec_itr->end(); ++s_itr) 
			ost << *s_itr;
		ost << '\n';
	}
	return ost;
}